#include "stdafx.h"
#include "TimeValue.h"

namespace RoomFW {


TimeValue::TimeValue(int32_t seconds, int32_t nanoSeconds) :
	seconds_(seconds),
	nanoSeconds_(nanoSeconds)
{
}


void TimeValue::set(int32_t seconds, int32_t nanoSeconds)
{
	seconds_ = seconds + (nanoSeconds / NanoSeconds);
	nanoSeconds_ = (nanoSeconds % NanoSeconds);
}

void TimeValue::setMilliseconds(int32_t ms)
{
	seconds_ = ms / MilliSeconds;
	nanoSeconds_ = (ms % MilliSeconds) * (NanoSeconds / MilliSeconds);
}


int32_t TimeValue::seconds(void) const
{
	return seconds_;
}


int32_t TimeValue::nanoSeconds(void) const
{
	return nanoSeconds_;
}

int32_t TimeValue::milliseconds(void) const
{
	return (seconds_ * MilliSeconds) + (nanoSeconds_ / (NanoSeconds / MilliSeconds));
}

bool TimeValue::operator==(const TimeValue& rhs) const
{
	return ((this->seconds_ == rhs.seconds_) &&
		(this->nanoSeconds_ == rhs.nanoSeconds_));
}


bool TimeValue::operator!=(const TimeValue& rhs) const
{
	return ((this->seconds_ != rhs.seconds_) ||
		(this->nanoSeconds_ != rhs.nanoSeconds_));
}


bool TimeValue::operator>(const TimeValue& rhs) const
{
	return ((this->seconds_ > rhs.seconds_) ||
		((this->seconds_ == rhs.seconds_) && 
		(this->nanoSeconds_ > rhs.nanoSeconds_)));
}


bool TimeValue::operator>=(const TimeValue& rhs) const
{
	return ((this->seconds_ > rhs.seconds_) ||
		((this->seconds_ == rhs.seconds_) && 
		(this->nanoSeconds_ >= rhs.nanoSeconds_)));
}


bool TimeValue::operator<(const TimeValue& rhs) const
{
	return ((this->seconds_ < rhs.seconds_) ||
		((this->seconds_ == rhs.seconds_) && 
		(this->nanoSeconds_ < rhs.nanoSeconds_)));
}


bool TimeValue::operator<=(const TimeValue& rhs) const
{
	return ((this->seconds_ < rhs.seconds_) ||
		((this->seconds_ == rhs.seconds_) && 
		(this->nanoSeconds_ <= rhs.nanoSeconds_)));
}


TimeValue TimeValue::operator+(const TimeValue& rhs) const
{
	TimeValue retVal;
	add(this->seconds_, this->nanoSeconds_, rhs.seconds_, rhs.nanoSeconds_, retVal.seconds_, retVal.nanoSeconds_);
	return retVal;
}


TimeValue TimeValue::operator-(const TimeValue& rhs) const
{
	TimeValue retVal;
	subtract(this->seconds_, this->nanoSeconds_, rhs.seconds_, rhs.nanoSeconds_, retVal.seconds_, retVal.nanoSeconds_);
	return retVal;
}


TimeValue& TimeValue::operator+=(const TimeValue& rhs)
{
	add(this->seconds_, this->nanoSeconds_, rhs.seconds_, rhs.nanoSeconds_, this->seconds_, this->nanoSeconds_);
	return *this;
}


TimeValue& TimeValue::operator-=(const TimeValue& rhs)
{
	subtract(this->seconds_, this->nanoSeconds_, rhs.seconds_, rhs.nanoSeconds_, this->seconds_, this->nanoSeconds_);
	return *this;
}


void TimeValue::add(int32_t s1, int32_t n1, int32_t s2, int32_t n2, int32_t& sr, int32_t& nr)
{
	sr = s1 + s2;
	nr = n1 + n2;
	if (nr >= NanoSeconds)
	{
		nr -= NanoSeconds;
		++sr;
	}
}


void TimeValue::subtract(int32_t s1, int32_t n1, int32_t s2, int32_t n2, int32_t& sr, int32_t& nr)
{
	sr = s1 - s2;
	nr = n1 - n2;
	if (nr < 0)
	{
		nr += NanoSeconds;
		--sr;
	}
}


}
